<?php
/**
 * DBShop 电子商务系统
 *
 * ==========================================================================
 * @link      https://www.dbshop.net/
 * @copyright 北京珑大钜商科技有限公司，并保留所有权利。
 * @license   https://www.dbshop.net/license.html License
 * ==========================================================================
 *
 * @author    静静的风 <baron@loongdom.cn>
 *
 */

namespace Operation\Controller;

use Admin\Controller\AdminActionController;
use Admin\Data\Common;
use Carbon\Carbon;
use Doctrine\ORM\EntityManager;
use Goods\Entity\GoodsClass;
use Laminas\Mvc\I18n\Translator;
use Operation\Entity\CouponCode;
use Operation\Entity\CouponCodeRule;
use Operation\Form\CouponCodeRuleForm;
use Operation\Form\CreateCouponCodeForm;
use Operation\Service\CouponCodeManager;
use Operation\Service\CouponCodeRuleManager;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Style\Alignment;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;

/**
 * 优惠码
 * Class CouponCodeController
 * @package Operation\Controller
 */
class CouponCodeController extends AdminActionController
{
    private $translator;
    private $entityManager;
    private $couponCodeRuleManager;
    private $couponCodeManager;

    public function __construct(
        Translator $translator,
        EntityManager $entityManager,
        CouponCodeRuleManager $couponCodeRuleManager,
        CouponCodeManager $couponCodeManager
    )
    {
        $this->translator       = $translator;
        $this->entityManager    = $entityManager;
        $this->couponCodeRuleManager    = $couponCodeRuleManager;
        $this->couponCodeManager        = $couponCodeManager;
    }

    /**
     * 优惠码规则列表
     * @return array
     */
    public function indexAction()
    {
        $couponCodeRule = $this->entityManager->getRepository(CouponCodeRule::class)->findCouponCodeRuleList();

        return ['couponCodeRule' => $couponCodeRule];
    }

    /**
     * 添加优惠码规则，并生成优惠码
     * @return array|\Laminas\Http\Response
     * @throws \Doctrine\ORM\ORMException
     * @throws \Doctrine\ORM\OptimisticLockException
     */
    public function addAction()
    {
        //商品分类
        $goodsClass = $this->entityManager->getRepository(GoodsClass::class)->findBy([], ['classTopId' => 'ASC', 'classSort' => 'ASC']);
        $classList  = Common::classOptions($goodsClass);
        //商品品牌
        $brandList  = $this->goodsPlugin()->goodsBrandOptions('', false);

        $form = new CouponCodeRuleForm();
        $form->get('couponCodeUserType')->setValueOptions(['allUser' => $this->translator->translate('所有客户'), 'userGroup' => $this->translator->translate('客户分组')]);
        $form->get('userGroup')->setValueOptions($this->userPlugin()->userGroupOptions('', false));
        $form->get('couponCodeGoodsType')->setValueOptions(['allGoods' => $this->translator->translate('所有商品'), 'goodsClass' => $this->translator->translate('商品分类'), 'goodsBrand' => $this->translator->translate('商品品牌')]);
        $form->get('goodsBrand')->setValueOptions($brandList);
        $form->get('goodsClass')->setValueOptions($this->goodsPlugin()->classValueArray($goodsClass));

        if($this->getRequest()->isPost()) {
            $postData = $this->params()->fromPost();
            $form->setData($postData);
            if ($form->isValid()) {
                $data = $form->getData();

                if(!empty($data['couponCodeStartTime']))  $data['couponCodeStartTime']  = Carbon::parse($data['couponCodeStartTime'])->timestamp;
                if(!empty($data['couponCodeEndTime']))    $data['couponCodeEndTime']    = Carbon::parse($data['couponCodeEndTime'].' 23:59:59')->timestamp;

                $data['couponCodeUserGroup']  = serialize((!in_array($data['couponCodeUserType'], ['allUser']) ? $data[$data['couponCodeUserType']] : []));
                $data['couponCodeGoodsBody']  = serialize((!in_array($data['couponCodeGoodsType'], ['allGoods']) ? $data[$data['couponCodeGoodsType']] : []));

                $codeRule = $this->couponCodeRuleManager->addCouponCodeRule($data);
                if ($codeRule) $this->couponCodeManager->addCouponCode($codeRule);

                $this->adminCommon()->addOperLog(sprintf($this->translator->translate('优惠码规则 %s 添加成功，并生成优惠!'), $codeRule->getCouponCodeTitle()), $this->translator->translate('优惠码'));

                return $this->redirect()->toRoute('operation-coupon-code');
            }
        }

        return [
            'form' => $form,
            'classList' => $classList,
            'brandList' => $brandList,
            'currencySymbol'=> Common::configValue('default', 'currency')['symbol']
        ];
    }

    /**
     * 编辑优惠码规则
     * @return array|\Laminas\Http\Response
     * @throws \Doctrine\ORM\ORMException
     * @throws \Doctrine\ORM\OptimisticLockException
     */
    public function editAction()
    {
        $couponCodeRuleId = (int) $this->params()->fromRoute('id', 0);
        $couponCodeRuleInfo = $this->entityManager->getRepository(CouponCodeRule::class)->findOneBy(['couponCodeRuleId' => $couponCodeRuleId]);
        if ($couponCodeRuleInfo == null) {
            $this->flashMessenger()->addWarningMessage($this->translator->translate('该优惠码规则不存在!'));
            return $this->redirect()->toRoute('operation-coupon-code');
        }

        //商品分类
        $goodsClass = $this->entityManager->getRepository(GoodsClass::class)->findBy([], ['classTopId' => 'ASC', 'classSort' => 'ASC']);
        $classList  = Common::classOptions($goodsClass);
        //商品品牌
        $brandList  = $this->goodsPlugin()->goodsBrandOptions('', false);

        $form = new CouponCodeRuleForm(true);
        $form->get('couponCodeUserType')->setValueOptions(['allUser' => $this->translator->translate('所有客户'), 'userGroup' => $this->translator->translate('客户分组')]);
        $form->get('userGroup')->setValueOptions($this->userPlugin()->userGroupOptions('', false));
        $form->get('couponCodeGoodsType')->setValueOptions(['allGoods' => $this->translator->translate('所有商品'), 'goodsClass' => $this->translator->translate('商品分类'), 'goodsBrand' => $this->translator->translate('商品品牌')]);
        $form->get('goodsBrand')->setValueOptions($brandList);
        $form->get('goodsClass')->setValueOptions($this->goodsPlugin()->classValueArray($goodsClass));

        if($this->getRequest()->isPost()) {
            $postData = $this->params()->fromPost();
            $form->setData($postData);
            if ($form->isValid()) {
                $data = $form->getData();

                if(!empty($data['couponCodeStartTime']))  $data['couponCodeStartTime']  = Carbon::parse($data['couponCodeStartTime'])->timestamp;
                if(!empty($data['couponCodeEndTime']))    $data['couponCodeEndTime']    = Carbon::parse($data['couponCodeEndTime'].' 23:59:59')->timestamp;

                $data['couponCodeUserGroup']  = serialize((!in_array($data['couponCodeUserType'], ['allUser']) ? $data[$data['couponCodeUserType']] : []));
                $data['couponCodeGoodsBody']  = serialize((!in_array($data['couponCodeGoodsType'], ['allGoods']) ? $data[$data['couponCodeGoodsType']] : []));

                $this->couponCodeRuleManager->editCouponCodeRule($data, $couponCodeRuleInfo);

                $this->adminCommon()->addOperLog(sprintf($this->translator->translate('充值码规则 %s 编辑成功!'), $couponCodeRuleInfo->getCouponCodeTitle()), $this->translator->translate('优惠码'));

                return $this->redirect()->toRoute('operation-coupon-code');
            }
        } else {
            $ruleArray = $couponCodeRuleInfo->valuesArray();
            $ruleArray['couponCodeStartTime']   = $ruleArray['couponCodeStartTime'] > 0 ? date("Y-m-d", $ruleArray['couponCodeStartTime']) : '';
            $ruleArray['couponCodeEndTime']     = $ruleArray['couponCodeEndTime'] > 0 ? date("Y-m-d", $ruleArray['couponCodeEndTime']) : '';
            $form->setData($ruleArray);
            if ($ruleArray['couponCodeUserType'] == 'userGroup') {
                $form->setData(['userGroup' => unserialize($ruleArray['couponCodeUserGroup'])]);
            }
        }

        return [
            'form' => $form,
            'classList' => $classList,
            'brandList' => $brandList,
            'couponCodeRuleInfo' => $couponCodeRuleInfo,
            'currencySymbol'=> Common::configValue('default', 'currency')['symbol']
        ];
    }

    /**
     * 优惠码列表
     * @return array|\Laminas\Http\Response
     */
    public function couponCodeListAction()
    {
        $couponCodeRuleId = (int) $this->params()->fromRoute('id', 0);
        $couponCodeRuleInfo = $this->entityManager->getRepository(CouponCodeRule::class)->findOneBy(['couponCodeRuleId' => $couponCodeRuleId]);
        if ($couponCodeRuleInfo == null) {
            $this->flashMessenger()->addWarningMessage($this->translator->translate('该优惠码规则不存在!'));
            return $this->redirect()->toRoute('operation-coupon-code');
        }

        $couponCodeList = $this->entityManager->getRepository(CouponCode::class)->findBy(['couponCodeRuleId' => $couponCodeRuleId], ['couponCodeId' => 'DESC']);

        return ['couponCodeRuleInfo' => $couponCodeRuleInfo, 'couponCodeList' => $couponCodeList];
    }

    /**
     * 优惠码导出
     * @return \Laminas\Http\PhpEnvironment\Response|\Laminas\Http\Response|\Laminas\Stdlib\ResponseInterface|mixed
     * @throws \PhpOffice\PhpSpreadsheet\Writer\Exception
     */
    public function exportCouponCodeAction()
    {
        $couponCodeRuleId = (int) $this->params()->fromRoute('id', 0);
        $couponCodeRuleInfo = $this->entityManager->getRepository(CouponCodeRule::class)->findOneBy(['couponCodeRuleId' => $couponCodeRuleId]);
        if ($couponCodeRuleInfo == null) {
            $this->flashMessenger()->addWarningMessage($this->translator->translate('该优惠码规则不存在!'));
            return $this->redirect()->toRoute('operation-coupon-code');
        }

        $codeState = $this->params()->fromPost('codeState', 0);
        if (!in_array($codeState, [1, 2, 3])) {
            $this->flashMessenger()->addWarningMessage($this->translator->translate('非正常状态导出!'));
            return $this->redirect()->toRoute('operation-coupon-code', ['action' => 'couponCodeList', 'id' => $couponCodeRuleId]);
        }

        $couponCodeList = $this->entityManager->getRepository(CouponCode::class)->findExportCouponCode($couponCodeRuleId, $codeState);

        $spreadsheet= new Spreadsheet();
        $spreadsheet->getProperties()->setCreator('DBShop');
        $spreadsheet->getActiveSheet()->getColumnDimension('A')->setWidth(30);
        $spreadsheet->getActiveSheet()->getColumnDimension('B')->setWidth(30);
        $spreadsheet->getActiveSheet()->getStyle('A')->getAlignment()->setHorizontal(Alignment::HORIZONTAL_LEFT);

        $sheet      = $spreadsheet->getActiveSheet();

        $sheet->setCellValue('A1', $this->translator->translate('规则(优惠码)名称'));
        $sheet->setCellValue('B1', $this->translator->translate('优惠码'));

        if ($couponCodeList) {
            $num = 2;
            foreach ($couponCodeList as $codeValue) {
                $sheet->setCellValueByColumnAndRow(1, $num, $couponCodeRuleInfo->getCouponCodeTitle());
                $sheet->setCellValueByColumnAndRow(2, $num, $codeValue->getCouponCodeStr());
                $num++;
            }
        }

        $response   = $this->getResponse();
        $headers    = $response->getHeaders();
        $headers->addHeaderLine("Content-type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        $headers->addHeaderLine("Content-Disposition: attachment;filename=".$this->translator->translate('优惠码').'-'.$couponCodeRuleInfo->getCouponCodeRuleId().".xlsx");
        $headers->addHeaderLine("Cache-Control: max-age=0");
        $response->sendHeaders();

        $writer = new Xlsx($spreadsheet);
        return $response->setContent($writer->save('php://output'));
    }

    /**
     * 优惠码规则删除
     * @return mixed
     * @throws \Doctrine\ORM\ORMException
     * @throws \Doctrine\ORM\OptimisticLockException
     */
    public function deleteAction()
    {
        if(!$this->adminCommon()->validatorCsrf()) return $this->adminCommon()->toReferer();

        $couponCodeRuleId = (int) $this->params()->fromRoute('id', 0);
        $couponCodeRuleInfo = $this->entityManager->getRepository(CouponCodeRule::class)->findOneBy(['couponCodeRuleId' => $couponCodeRuleId]);
        if ($couponCodeRuleInfo == null) {
            $this->flashMessenger()->addWarningMessage($this->translator->translate('该优惠码规则不存在!'));
            return $this->adminCommon()->toReferer();
        }

        $this->couponCodeRuleManager->deleteCouponCodeRule($couponCodeRuleInfo);
        $this->couponCodeManager->deleteCouponAllCode($couponCodeRuleId);

        $this->adminCommon()->addOperLog(sprintf($this->translator->translate('优惠码规则 %s 删除成功!'), $couponCodeRuleInfo->getCouponCodeTitle()), $this->translator->translate('优惠码'));

        return $this->adminCommon()->toReferer();
    }

    /**
     * 优惠码生成
     * @return array|\Laminas\Http\Response
     * @throws \Doctrine\ORM\ORMException
     * @throws \Doctrine\ORM\OptimisticLockException
     */
    public function createCouponCodeAction()
    {
        $couponCodeRuleId = (int) $this->params()->fromRoute('id', 0);
        $couponCodeRuleInfo = $this->entityManager->getRepository(CouponCodeRule::class)->findOneBy(['couponCodeRuleId' => $couponCodeRuleId]);
        if ($couponCodeRuleInfo == null) {
            $this->flashMessenger()->addWarningMessage($this->translator->translate('该优惠码规则不存在!'));
            return $this->redirect()->toRoute('operation-coupon-code');
        }

        $form = new CreateCouponCodeForm();

        if ($this->getRequest()->isPost()) {
            $postData = $this->params()->fromPost();
            $form->setData($postData);
            if ($form->isValid()) {
                $data = $form->getData();
                $this->couponCodeRuleManager->editCouponCodeRule(['codeNum' => $couponCodeRuleInfo->getCodeNum() + $data['codeNum']], $couponCodeRuleInfo);
                $this->couponCodeManager->addCouponCode($couponCodeRuleInfo, $data['codeNum']);

                $this->adminCommon()->addOperLog(sprintf($this->translator->translate('优惠码 %s 生成成功!'), $couponCodeRuleInfo->getCouponCodeTitle()), $this->translator->translate('优惠码'));
                return $this->redirect()->toRoute('operation-coupon-code');
            }
        }

        return [
            'form' => $form,
            'couponCodeRuleInfo'  => $couponCodeRuleInfo
        ];
    }
}